package com.whacos.modules.oa.service.impl;

import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.whacos.modules.oa.dao.NotifyDao;
import com.whacos.modules.oa.dao.NotifyRecordDao;
import com.whacos.modules.oa.entity.Notify;
import com.whacos.modules.oa.dto.NotifyDTO;
import com.whacos.modules.oa.entity.NotifyRecord;
import com.whacos.modules.oa.service.NotifyService;
import com.whacos.modules.system.dao.SysUserDao;
import com.whacos.modules.system.entity.SysUser;
import com.whacos.modules.system.service.SessionService;
import com.whacos.modules.system.service.DictService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.messaging.simp.SimpMessagingTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * @author xiongdun
 * @description 通知通告发送记录
 * @since 2018/11/17 17:11
 */
@Service
public class NotifyServiceImpl extends ServiceImpl<NotifyDao, Notify> implements NotifyService {
    @Autowired
    private NotifyDao notifyDao;
    @Autowired
    private NotifyRecordDao notifyRecordDao;
    @Autowired
    private SysUserDao sysUserDao;
    @Autowired
    private DictService dictService;
    @Autowired
    private SessionService sessionService;
    @Autowired
    private SimpMessagingTemplate template;

    //给在线用户发送通知
    private static ThreadPoolExecutor executor = new ThreadPoolExecutor(1, 1, 0,
            TimeUnit.MILLISECONDS, new LinkedBlockingDeque<>());

    @Override
    public Notify getOne(Wrapper<Notify> queryWrapper) {
        Notify notify = notifyDao.selectOne(queryWrapper);
        notify.setType(dictService.getName("oa_notify_type", notify.getType()));
        return notify;
    }

    @Override
    public List<Notify> list(Wrapper<Notify> queryWrapper) {
        List<Notify> notifyList = notifyDao.selectList(queryWrapper);
        notifyList.forEach(notify -> notify.setType(dictService.getName("oa_notify_type", notify.getType())));
        return notifyList;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean save(Notify entity) {
        entity.createdData(entity.getUserId());
        // 保存到接受者列表中
        int result = this.notifyDao.insert(entity);
        Long[] userIds = entity.getUserIds();
        Long notifyId = entity.getId();
        List<NotifyRecord> notifyRecordList = new ArrayList<>();
        for (Long userId : userIds) {
            NotifyRecord notifyRecord = new NotifyRecord();
            notifyRecord.setNotifyId(notifyId);
            notifyRecord.setUserId(userId);
            notifyRecord.setIsRead(0);
            notifyRecordList.add(notifyRecord);
        }
        notifyRecordDao.batchInsert(notifyRecordList);

        executor.execute(() -> {
            for (SysUser userDO : sessionService.listOnlineUser()) {
                for (Long userId : userIds) {
                    if (userId.equals(userDO.getId())) {
                        template.convertAndSendToUser(userDO.toString(),
                                "/queue/notifications", "新消息：" + entity.getTitle());
                    }
                }
            }

        });
        executor.shutdown();
        return result > 0;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean removeById(Serializable id) {
        boolean result = false;
        // 按 notifyId 刪除notifyRecord 通知记录
        if (this.notifyRecordDao.delete(new LambdaQueryWrapper<NotifyRecord>()
                .eq(NotifyRecord::getNotifyId, id)) > 0) {
            if (this.notifyDao.deleteById(id) > 0) {
                result = true;
            }
        }
        return result;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean batchRemove(List<Long> idList) {
        boolean result = false;
        // 按 notifyId 集合批量删除通知记录表 notifyRecord
        if (this.notifyRecordDao.delete(new LambdaQueryWrapper<NotifyRecord>()
                .in(NotifyRecord::getNotifyId, idList)) > 0) {
            if (notifyDao.deleteBatchIds(idList) > 0) {
                result = true;
            }
        }
        return result;
    }

    @Override
    public IPage<NotifyDTO> selfList(IPage<NotifyDTO> page, NotifyRecord notifyRecord) {
        IPage<NotifyDTO> notifyList = notifyDao.pageNotifyDTOList(page,
                notifyRecord.getId(),
                notifyRecord.getIsRead(),
                notifyRecord.getUserId(),
                notifyRecord.getReadDate(),
                notifyRecord.getNotifyId());

        for (NotifyDTO notifyDTO : notifyList.getRecords()) {
            //notifyDTO.setBefore(DateUtils.getTimeBefore(notifyDTO.getUpdatedDate().toString()));
            notifyDTO.setSender(sysUserDao.selectById(notifyDTO.getCreatedBy()).getRealName());
        }
        return notifyList;
    }

}
